package com.example.demo.demos.web.Utils;

import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.xmlbeans.XmlException;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import org.apache.poi.xwpf.usermodel.*;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * @version V1.0
 * @Description：Word模板数据填充
 * @Date: 2022/11/16 17:47
 */
public class ReplaceWord {

    /***
     * @Description :替换段落文本
     * @param document docx解析对象
     * @param textMap  需要替换的信息集合
     * @return void
     * @Date 2022/11/17 17:22
     */
    public static void changeText(XWPFDocument document, Map<String, Object> textMap) {
        // 获取段落集合
        Iterator<XWPFParagraph> iterator = document.getParagraphsIterator();
        XWPFParagraph paragraph = null;
        while (iterator.hasNext()) {
            paragraph = iterator.next();
            // 判断此段落是否需要替换
            if (checkText(paragraph.getText())) {
                replaceValue(paragraph, textMap);
            }
        }
    }

    /***
     * @Description :检查文本中是否包含指定的字符(此处为“$”)
     * @param text
     * @return boolean
     * @Date 2022/11/17 17:22
     */
    public static boolean checkText(String text) {
        boolean check = false;
        if (text.contains("$")) {
            check = true;
        }
        return check;
    }

    /**
     * 替换图片
     *
     * @param document
     * @param picData
     * @throws Exception
     */

    public static void changePic(XWPFDocument document, Map<String, Object> picData) throws Exception {
        // 获取段落集合
        Iterator<XWPFParagraph> iterator = document.getParagraphsIterator();
        XWPFParagraph paragraph;
        while (iterator.hasNext()) {
            paragraph = iterator.next();
            // 判断此段落是否需要替换
            String text = paragraph.getText();
            if (checkText(text)) {
                replacePicValue(paragraph, picData);
            }
        }
    }

    /***
     * @Description :替换表格内的文字
     * @param document
     * @param data
     * @return void
     * @Date 2022/11/18 11:29
     */
    public static void changeTableText(XWPFDocument document, Map<String, Object> data) {
        // 获取文件的表格
        Iterator<XWPFTable> tableList = document.getTablesIterator();
        XWPFTable table;
        List<XWPFTableRow> rows;
        List<XWPFTableCell> cells;
        // 循环所有需要进行替换的文本，进行替换
        while (tableList.hasNext()) {
            table = tableList.next();
            if (checkText(table.getText())) {
                rows = table.getRows();
                // 遍历表格，并替换模板
                for (XWPFTableRow row : rows) {
                    cells = row.getTableCells();
                    for (XWPFTableCell cell : cells) {
                        // 判断单元格是否需要替换
                        if (checkText(cell.getText())) {
                            List<XWPFParagraph> paragraphs = cell.getParagraphs();
                            for (XWPFParagraph paragraph : paragraphs) {
                                replaceValue(paragraph, data);
                            }
                        }
                    }
                }
            }
        }
    }

    /***
     * @Description :替换表格内图片
     * @param document
     * @param picData
     * @return void
     * @Date 2022/11/18 11:29
     */
    public static void changeTablePic(XWPFDocument document, Map<String, Object> picData) throws Exception {
        // 获取文件的表格
        Iterator<XWPFTable> tableList = document.getTablesIterator();
        XWPFTable table;
        List<XWPFTableRow> rows;
        List<XWPFTableCell> cells;
        // 循环所有需要进行替换的文本，进行替换
        while (tableList.hasNext()) {
            table = tableList.next();
            if (checkText(table.getText())) {
                rows = table.getRows();
                // 遍历表格，并替换模板
                for (XWPFTableRow row : rows) {
                    cells = row.getTableCells();
                    for (XWPFTableCell cell : cells) {
                        // 判断单元格是否需要替换
                        if (checkText(cell.getText())) {
                            List<XWPFParagraph> paragraphs = cell.getParagraphs();
                            for (XWPFParagraph paragraph : paragraphs) {
                                replacePicValue(paragraph, picData);
                            }
                        }
                    }
                }
            }
        }
    }

    /***
     * @Description :替换内容
     * @param paragraph
     * @param textMap
     * @return void
     * @Date 2022/11/18 11:33
     */
    public static void replaceValue(XWPFParagraph paragraph, Map<String, Object> textMap) {
        XWPFRun run, nextRun;
        String runsText;
        List<XWPFRun> runs = paragraph.getRuns();
        for (int i = 0; i < runs.size(); i++) {
            run = runs.get(i);
            runsText = run.getText(0);
            if (runsText.contains("${") || (runsText.contains("$"))) {
                while (!runsText.contains("}")) {
                    nextRun = runs.get(i + 1);
                    runsText = runsText + nextRun.getText(0);
                    //删除该节点下的数据
                    paragraph.removeRun(i + 1);
                }
                Object value = changeValue(runsText, textMap);
                //判断key在Map中是否存在
                if (textMap.containsKey(runsText)) {
                    run.setText(value.toString(), 0);
                } else {
                    //如果匹配不到，则不修改
                    run.setText(runsText, 0);
                }
            }
        }
    }

    /***
     * @Description :替换图片内容
     * @param paragraph
     * @param picData
     * @return void
     * @Date 2022/11/18 11:33
     */
    public static void replacePicValue(XWPFParagraph paragraph, Map<String, Object> picData) throws Exception {
        List<XWPFRun> runs = paragraph.getRuns();
        for (XWPFRun run : runs) {
            Object value = changeValue(run.toString(), picData);
            if (picData.containsKey(run.toString())) {
                //清空内容
                run.setText("", 0);
                FileInputStream is = new FileInputStream((String) value);
                //图片宽度、高度
                int width = Units.toEMU(100), height = Units.toEMU(100);
                //添加图片信息，段落高度需要在模板中自行调整
                run.addPicture(is, XWPFDocument.PICTURE_TYPE_PNG, (String) value, width, height);
            }
        }
    }

    /***
     * @Description :匹配参数
     * @param value
     * @param textMap
     * @return java.lang.Object
     * @Date 2022/11/18 11:33
     */
    public static Object changeValue(String value, Map<String, Object> textMap) {
        Object valu = "";
        for (Map.Entry<String, Object> textSet : textMap.entrySet()) {
            // 匹配模板与替换值 格式${key}
            String key = textSet.getKey();
            if (value.contains(key)) {
                valu = textSet.getValue();
            }
        }
        return valu;
    }

/*    public static void operateWord(Map<String, Object> data, Map<String, Object> picData){
        try {
            FileInputStream is = new FileInputStream("/Users/hu1er/IdeaProjects/demo1/src/main/resources/template/template.docx");
            XWPFDocument document = new XWPFDocument(is);
            if (data.size() > 0) {
                // 替换掉表格之外的文本(仅限文本)
                ReplaceWord.changeText(document, data);
                // 替换表格内的文本对象
                ReplaceWord.changeTableText(document, data);
            }
            if (picData.size() > 0) {
                // 替换内容图片
                ReplaceWord.changePic(document, picData);
                // 替换表格内的图片对象
                ReplaceWord.changeTablePic(document, picData);
            }
            FileOutputStream out = new FileOutputStream("/Users/hu1er/IdeaProjects/demo1/src/main/resources/template/test.docx");
            document.write(out);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

*//*    public static void main (String[] args) {
            Map<String, Object> data = new HashMap<>();
            Map<String, Object> picData = new HashMap<>();
            data.put("${aab999}", "123456789");
            data.put("${aac003}", "刘毅");
            data.put("${aac147}", "43102119001212109X");
            data.put("${aae004}", "刘毅");
            data.put("${aae005}", "13800000000");
            data.put("${aae013}", "");
            data.put("${aae123}", "刘毅");
            data.put("${aae123_1}", "");
            data.put("${aae123_2}", "");
            data.put("${aae124}", "刘小毅");
            data.put("${aae124_1}", "");
            data.put("${aae124_2}", "");
            picData.put("${aac013}", "C:\\Users\\Liu\\Pictures\\26ed64f74a659d46d6db0fd979bc0142.jpeg");
            operateWord(data, picData);
        }*//*

    }*/
public static void operateWord(Map<String, Object> data){
    try {
        FileInputStream is = new FileInputStream("/Users/hu1er/IdeaProjects/demo1/src/main/resources/template/template.docx");
        XWPFDocument document = new XWPFDocument(is);
        if (data.size() > 0) {
            // 替换掉表格之外的文本(仅限文本)
            ReplaceWord.changeText(document, data);
            // 替换表格内的文本对象
            ReplaceWord.changeTableText(document, data);
        }
        FileOutputStream out = new FileOutputStream("/Users/hu1er/IdeaProjects/demo1/src/main/resources/report/report1.docx");
        document.write(out);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }

}

    /**
     * @Description 创建表格
     * @author Hu1er
     * @version 1.17.0
     * @date 2023/7/4
     */
    public static void createTable(XWPFDocument document, String reportPath) throws IOException, XmlException {

        //获取模板文件样式
        CTStyles styles = document.getStyle();
        //设置新建文档样式为模板中读取到的样式
        XWPFStyles docStyle = document.createStyles();
        docStyle.setStyles(styles);

        // 追加创建标题
        XWPFParagraph title = document.createParagraph();
        //设置标题样式
        title.setStyle("3");
        XWPFRun run = title.createRun();
        //设置标题名称
        run.setText("段落标题");

        // 追加创建五行两列的表格
        XWPFTable table = document.createTable(5, 2);

        // 设置表格样式
        CTTblPr tblPr = table.getCTTbl().getTblPr();
        CTJc jc = tblPr.addNewJc();
        jc.setVal(STJc.CENTER);

        CTTblWidth tableWidth = tblPr.addNewTblW();
        tableWidth.setType(STTblWidth.DXA);
        tableWidth.setW(BigInteger.valueOf((long) (567 * 14.57)));

        String[] content = new String[]{"风险名称", "风险级别", "风险描述", "测试过程", "加固建议"};
        // 添加数据行
        CTTcPr tcpr = null;
        CTTblWidth cellw = null;
        for (int i = 0; i < 5; i++) {
            XWPFTableRow dataRow = table.getRow(i);
            dataRow.getCell(0).setColor("63B8FF");
            dataRow.getCell(0).setText(content[i]);
            tcpr = dataRow.getCell(0).getCTTc().addNewTcPr();
            cellw = tcpr.addNewTcW();
            cellw.setType(STTblWidth.DXA);
            cellw.setW(BigInteger.valueOf((long) (567 * 2.37)));
        }

        // 保存新生成的 Word 文件
        FileOutputStream fos = new FileOutputStream(reportPath);
        document.write(fos);
        fos.close();

    }
}


